package com.atguigu.yygh.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.yygh.enums.PaymentTypeEnum;
import com.atguigu.yygh.enums.RefundStatusEnum;
import com.atguigu.yygh.exception.YYGHException;
import com.atguigu.yygh.model.order.OrderInfo;
import com.atguigu.yygh.model.order.PaymentInfo;
import com.atguigu.yygh.model.order.RefundInfo;
import com.atguigu.yygh.order.prop.WeiPayProperties;
import com.atguigu.yygh.order.service.OrderInfoService;
import com.atguigu.yygh.order.service.PaymentService;
import com.atguigu.yygh.order.service.RefundInfoService;
import com.atguigu.yygh.order.service.WeiPayService;
import com.atguigu.yygh.order.utils.HttpClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.wxpay.sdk.WXPayUtil;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/*==========================================
      时 间:   2022-04-28
      讲 师:   刘  辉
      描 述:   尚硅谷教学团队
 ==========================================*/
@Service
public class WeiPayServiceImpl implements WeiPayService {

    @Autowired
    private OrderInfoService orderInfoService;
    @Autowired
    private PaymentService paymentService;
    @Autowired
    private WeiPayProperties weiPayProperties;
    @Autowired
    private RefundInfoService refundInfoService;

    @Override
    public String createNative(Long orderId) {
        //1.根据订单id获取订单信息
        OrderInfo orderInfo = orderInfoService.getById(orderId);
        //2.保存支付记录
        paymentService.savePaymentInfo(orderInfo, PaymentTypeEnum.WEIXIN.getStatus());

        //3.请求微信服务器：
        Map paramMap = new HashMap();
        paramMap.put("appid", weiPayProperties.getAppid());
        paramMap.put("mch_id", weiPayProperties.getPartner());

        paramMap.put("nonce_str", WXPayUtil.generateNonceStr());

        Date reserveDate = orderInfo.getReserveDate();
        String reserveDateString = new DateTime(reserveDate).toString("yyyy/MM/dd");
        String body = reserveDateString + "就诊"+ orderInfo.getDepname();
        paramMap.put("body", body);

        paramMap.put("out_trade_no", orderInfo.getOutTradeNo());
        //paramMap.put("total_fee", order.getAmount().multiply(new BigDecimal("100")).longValue()+"");
        paramMap.put("total_fee","1");//为了测试

        paramMap.put("spbill_create_ip", "127.0.0.1");
        paramMap.put("notify_url", "http://guli.shop/api/order/weixinPay/weixinNotify");
        paramMap.put("trade_type", "NATIVE");

        try{
            HttpClient httpClient=new HttpClient("https://api.mch.weixin.qq.com/pay/unifiedorder");
            httpClient.setXmlParam(WXPayUtil.generateSignedXml(paramMap, weiPayProperties.getPartnerkey()));
            httpClient.setHttps(true);
            httpClient.post();
            String content = httpClient.getContent();
            Map<String, String> stringStringMap = WXPayUtil.xmlToMap(content);
            System.out.println(stringStringMap);

            return stringStringMap.get("code_url");
        }catch (Exception ex){
            throw new YYGHException(2001,"获取二维码失败");
        }
    }

    @Override
    public Map<String, String> getOrderStatus(Long orderId) {
        OrderInfo orderInfo = orderInfoService.getById(orderId);

        Map paramMap = new HashMap<>();
        paramMap.put("appid", weiPayProperties.getAppid());
        paramMap.put("mch_id", weiPayProperties.getPartner());
        paramMap.put("out_trade_no", orderInfo.getOutTradeNo());
        paramMap.put("nonce_str",WXPayUtil.generateNonceStr());
        HttpClient httpClient=new HttpClient("https://api.mch.weixin.qq.com/pay/orderquery");

        try{
            httpClient.setXmlParam(WXPayUtil.generateSignedXml(paramMap, weiPayProperties.getPartnerkey()));
            httpClient.setHttps(true);
            httpClient.post();
            String content = httpClient.getContent();
            Map<String, String> stringStringMap = WXPayUtil.xmlToMap(content);
            return stringStringMap;
        }catch (Exception ex){
            return  null;
        }
    }


    @Override
    public boolean refund(Long orderId) {
        //1.根据订单id支付记录信息
        QueryWrapper<PaymentInfo> queryWrapper=new QueryWrapper<PaymentInfo>();
        queryWrapper.eq("order_id",orderId);
        PaymentInfo one = paymentService.getOne(queryWrapper);
        //2.向退款记录表中添加一条退款记录
        RefundInfo refundInfo = refundInfoService.saveRefundInfo(one);
        if(refundInfo.getRefundStatus().intValue() == RefundStatusEnum.REFUND.getStatus().intValue()){
            return true;
        }

        //请求微信服务器
        Map<String,String> paramMap = new HashMap<>(8);
        paramMap.put("appid",weiPayProperties.getAppid());       //公众账号ID
        paramMap.put("mch_id",weiPayProperties.getPartner());   //商户编号
        paramMap.put("nonce_str",WXPayUtil.generateNonceStr());

        paramMap.put("transaction_id",one.getTradeNo()); //微信订单号
        paramMap.put("out_trade_no",one.getOutTradeNo()); //商户订单编号

        paramMap.put("out_refund_no","tk"+one.getOutTradeNo()); //商户退款单号
        //       paramMap.put("total_fee",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
        //       paramMap.put("refund_fee",paymentInfoQuery.getTotalAmount().multiply(new BigDecimal("100")).longValue()+"");
        paramMap.put("total_fee","1");
        paramMap.put("refund_fee","1");


        HttpClient httpClient=new HttpClient("https://api.mch.weixin.qq.com/secapi/pay/refund");


        try{
            httpClient.setXmlParam(WXPayUtil.generateSignedXml(paramMap, weiPayProperties.getPartnerkey()));
            httpClient.setHttps(true);

            httpClient.setCert(true);
            httpClient.setCertPassword(weiPayProperties.getPartner());

            httpClient.post();//发送请求
            String content = httpClient.getContent();
            Map<String, String> stringStringMap = WXPayUtil.xmlToMap(content);
            if(stringStringMap.get("result_code").equals("SUCCESS")){

                RefundInfo refundInfo1=new RefundInfo();

                refundInfo.setCallbackTime(new Date());
                refundInfo.setTradeNo(stringStringMap.get("refund_id"));
                refundInfo.setRefundStatus(RefundStatusEnum.REFUND.getStatus());
                refundInfo.setCallbackContent(JSONObject.toJSONString(stringStringMap));
                refundInfoService.updateById(refundInfo);
                return true;
            }

            return false;
        }catch (Exception ex){
            ex.printStackTrace();
            return false;
        }

    }
}
